<?php


namespace Aoe\Util\Manager;

use Aoe\Util\Swap\Rom;
use Iterator;
use Throwable;

/**
 * # 数组定义元素管理器
 *
 * @template T extend object
 * @extends Collection<T>
 */
abstract class NamedCollection extends Collection
{
    /**
     * @var Rom
     */
    protected Rom $named_items;
    
    public function __construct(array $defs)
    {
        $this->named_items = new Rom(array_change_key_case($defs));
    }
    
    public function has(string $name): bool
    {
        return parent::has($name) || $this->named_items->has(strtolower($name));
    }
    
    public function getKeys(): array
    {
        return $this->named_items->getKeys();
    }

    /**
     * @param string[]|null $items
     * @return Iterator<mixed, T>
     */
    public function getIterator(null | array $items = null): Iterator
    {
        if ($items === null) $items = $this->getKeys();
        
        foreach ($items as $item) {
            if ($this->has($item)) try {
                yield $this->get($item);
            } catch (Throwable) {}
        }
    }
}